package LeetDev.a3d;

import java.io.IOException;
import java.util.*;

import javax.microedition.khronos.opengles.GL10;

public class Model {
	private static HashMap<String, Model> s_models=new HashMap<String, Model>(); 
	public static String s_modelPath;

	private int m_references;
	private String m_file;
	public ImpObj m_ImpObjs[];
	public Anim m_anims[];
	private Material m_materials[];
	public int m_hierarchy[];
	
	public static Model create(final String file, GL10 gl) throws Exception
	{
		String tfile=s_modelPath+file;

		Object t=s_models.get(tfile);
		if(t!=null)
		{
			Model mt=(Model)t;
			mt.addRef();
			return(mt);
		}
		Model ret=new Model(tfile,gl);
		s_models.put(tfile,ret);
		return(ret);
	}

	public static void destroy(Model model, GL10 gl)
	{
		if(model.subRef())
		{
			s_models.remove(model.m_file);
		}
		for(int t=0;t<model.m_materials.length;++t)
		{
			model.m_materials[t].destruct(gl);
		}
	}

	private Model()
	{
		m_references=1;
	}

	private Model(final String file,GL10 gl) throws Exception
	{
		m_references=1;
		m_file=file;
		int i;
		
		String tmpstring;

		String extension=m_file.substring(m_file.indexOf('.')+1);
		if(extension.compareTo("gun")==0)
		{
			// This Model is a gun file, import it.
			FileInput fin=new FileInput(m_file);

			int magic1,magic2;
			magic1=fin.popInt();
			magic2=fin.popInt();
			if(magic1!=0xb1d4abad||magic2!=0x2b17fac)
			{
				throw( new IOException(file+" is not a .gun file!"));
			}

			int materialnum;
			materialnum=fin.popInt();
			m_materials=new Material[materialnum];
			// load materials
			for(i=0;i<materialnum;i++)
			{
				m_materials[i]=new Material(fin,gl);
			}
			int objectnum;
			objectnum=fin.popInt();
			m_ImpObjs=new ImpObj[objectnum];
			for(i=0;i<objectnum;i++)
			{
				byte objtype;
				tmpstring=fin.popString();
				objtype=fin.popByte();
				if(objtype==0)
				{
					Mesh tmpmesh=new Mesh(fin,tmpstring,objtype,m_materials,gl);
					m_ImpObjs[i]=(ImpObj)tmpmesh;
				}
				if(objtype==1)
				{
					Joint tmpjoint=new Joint(fin,tmpstring,objtype);
					m_ImpObjs[i]=(ImpObj)tmpjoint;
				}
			}
			int animnum;
			animnum=fin.popInt();
			m_anims=new Anim[animnum];
//			m_hierarchy=new int[animnum];
			int tmpHierarchy[]=new int[animnum*2];
			
			int fps,frames;
			fps=fin.popInt();
			frames=fin.popInt();
			int hNum=0;
			for(i=0;i<animnum;i++)
			{
				int parentnode,objectref;
				tmpstring=fin.popString();
				parentnode=fin.popInt();
				objectref=fin.popInt();
				if(objectref!=-1)
				{
					tmpHierarchy[hNum++]=i+1; // object
					tmpHierarchy[hNum++]=objectref; // object
				}
				m_anims[i]=(Anim) new DecomposedAnim(fin,tmpstring,frames,fps,parentnode+1);	// We will later use the animation with an array that is offsetted by one, thats why we add one to the parentnode.
			}
			m_hierarchy=new int[hNum];
			System.arraycopy(tmpHierarchy,0,m_hierarchy,0,hNum);
			// This is the file end, test it, and report error if we can read more.
			byte wanterror;
			try {
				wanterror=fin.popByte();
				wanterror=0;
			}
			catch(Exception e)
			{
				wanterror=1;
			}
			if(wanterror!=1)
			{
				throw( new IOException(file+" have unexpected data!"));
			}
		}
		else
		{
			throw( new IOException(file+" unsupported file format!"));
		}
		/*
		else
		{
			// This Model is an Image Model, load the image and create the Model.
			m_type=Image;
			Material *tmpmaterial=new Material(m_file);
			m_materials.push_back(tmpmaterial);
//			m_ImpObjs.push_back(new Mesh(tmpmaterial));

			Mesh *tmpmesh=new Mesh(tmpmaterial);
			if(extensionCreator!=NULL)
			{
				tmpmesh->SetExtension(extensionCreator(*tmpmesh));
			}
			m_ImpObjs.push_back(tmpmesh);

			m_hierarchy.push_back(1);	// nodenum
			m_hierarchy.push_back(0); // object
			m_anims.push_back(new DecomposedAnim(m_file));
		}
		*/
	}

	public void addRef()
	{
		++m_references;
	}

	public boolean subRef()
	{
		return((--m_references)<=0);
	}

}
